home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 42 / Amiga Format AFCD42 (Issue 126, Aug 1999).iso / -serious- / programming / other / jikes / src / symbol.cpp < prev    next >
C/C++ Source or Header  |  1999-05-14  |  65KB  |  1,763 lines

  1. // $Id: symbol.cpp,v 1.11 1999/03/09 14:37:17 shields Exp $
  2. //
  3. // This software is subject to the terms of the IBM Jikes Compiler Open
  4. // Source License Agreement available at the following URL:
  5. // http://www.ibm.com/research/jikes.
  6. // Copyright (C) 1996, 1998, International Business Machines Corporation
  7. // and others.  All Rights Reserved.
  8. // You must accept the terms of that agreement to use this software.
  9. //
  10. #include "config.h"
  11. #include <sys/stat.h>
  12. #include <assert.h>
  13. #include "stream.h"
  14. #include "control.h"
  15. #include "ast.h"
  16. #include "semantic.h"
  17. #include "table.h"
  18. #include "zip.h"
  19.  
  20. #if defined(UNIX_FILE_SYSTEM) || defined(AMIGAOS_FILE_SYSTEM)
  21. #include <dirent.h>
  22. #elif defined(WIN32_FILE_SYSTEM)
  23. #include <windows.h>
  24. #endif
  25.  
  26. char *FileSymbol::java_suffix = StringConstant::U8S__DO_java;
  27. int FileSymbol::java_suffix_length = strlen(java_suffix);
  28. char *FileSymbol::class_suffix = StringConstant::U8S__DO_class;
  29. int FileSymbol::class_suffix_length = strlen(class_suffix);
  30.  
  31. bool MethodSymbol::IsFinal()
  32. {
  33.     return ((AccessFlags *) this) -> ACC_FINAL() || ((AccessFlags *) this) -> ACC_PRIVATE() || containing_type -> ACC_FINAL();
  34. }
  35.  
  36. wchar_t *MethodSymbol::Header(Semantic *sem, LexStream::TokenIndex token_location)
  37. {
  38.     if (! this -> IsTyped())
  39.         this -> ProcessMethodSignature(sem, token_location);
  40.  
  41.     if (! header)
  42.     {
  43.         bool is_constructor = false;
  44.         for (MethodSymbol *constr = containing_type -> FindConstructorSymbol(); constr; constr = constr -> next_method)
  45.         {
  46.             if (this == constr)
  47.             {
  48.                 is_constructor = true;
  49.                 break;
  50.             }
  51.         }
  52.  
  53.         int length = this -> Type() -> ContainingPackage() -> PackageNameLength() +
  54.                      this -> Type() -> ExternalNameLength() +
  55.                      (is_constructor ? containing_type -> NameLength() : this -> NameLength()) + 5; // '/' after package_name
  56.                                                                                                     // ' ' after type
  57.                                                                                                     // '(' after name
  58.                                                                                                     // ')' after all parameters
  59.                                                                                                     // ';' to terminate
  60.         for (int i = 0; i < NumFormalParameters(); i++)
  61.         {
  62.             VariableSymbol *formal = FormalParameter(i);
  63.             length += (formal -> Type() -> ContainingPackage() -> PackageNameLength() +
  64.                        formal -> Type() -> ExternalNameLength() +
  65.                        formal -> NameLength() + 4); // '/' after package_name
  66.                                                     // ' ' after type
  67.                                                     // ',' and ' ' to separate this formal parameter from the next one
  68.         }
  69.  
  70.         header = new wchar_t[length + 1]; // +1 for '\0'
  71.         wchar_t *s = header;
  72.  
  73.         if (is_constructor)
  74.         {
  75.             for (wchar_t *s2 = this -> containing_type -> Name(); *s2; s2++)
  76.                  *s++ = *s2;
  77.         }
  78.         else
  79.         {
  80.             PackageSymbol *package = this -> Type() -> ContainingPackage();
  81.             wchar_t *package_name = package -> PackageName();
  82.             if (package -> PackageNameLength() > 0 && wcscmp(package_name, StringConstant::US__DO_) != 0)
  83.             {
  84.                 while (*package_name)
  85.                 {
  86.                     *s++ = (*package_name == U_SLASH ? (wchar_t) U_DOT : *package_name);
  87.                     package_name++;
  88.                 }
  89.                 *s++ = U_DOT;
  90.             }
  91.  
  92.             for (wchar_t *s2 = this -> Type() -> ExternalName(); *s2; s2++)
  93.                  *s++ = *s2;
  94.             *s++ = U_SPACE;
  95.             for (wchar_t *s3 = Name(); *s3; s3++)
  96.                  *s++ = *s3;
  97.         }
  98.         *s++ = U_LEFT_PARENTHESIS;
  99.         if (NumFormalParameters() > 0)
  100.         {
  101.             for (int k = 0; k < NumFormalParameters(); k++)
  102.             {
  103.                 VariableSymbol *formal = FormalParameter(k);
  104.  
  105.                 PackageSymbol *package = formal -> Type() -> ContainingPackage();
  106.                 wchar_t *package_name = package -> PackageName();
  107.                 if (package -> PackageNameLength() > 0 && wcscmp(package_name, StringConstant::US__DO_) != 0)
  108.                 {
  109.                     while (*package_name)
  110.                     {
  111.                         *s++ = (*package_name == U_SLASH ? (wchar_t) U_DOT : *package_name);
  112.                         package_name++;
  113.                     }
  114.                     *s++ = U_DOT;
  115.                 }
  116.  
  117.                 for (wchar_t *s2 = formal -> Type() -> ExternalName(); *s2; s2++)
  118.                     *s++ = *s2;
  119.                 *s++ = U_SPACE;
  120.                 for (wchar_t *s3 = formal -> Name(); *s3; s3++)
  121.                      *s++ = *s3;
  122.                 *s++ = U_COMMA;
  123.                 *s++ = U_SPACE;
  124.             }
  125.  
  126.             s -= 2; // remove the last ',' and ' '
  127.         }
  128.         *s++ = U_RIGHT_PARENTHESIS;
  129.         *s++ = U_SEMICOLON;
  130.         *s = U_NULL;
  131. assert((s - header) <= length);
  132.     }
  133.  
  134.     return header;
  135. }
  136.  
  137.  
  138. MethodSymbol *SymbolTable::FindOverloadMethod(MethodSymbol *base_method, AstMethodDeclarator *method_declarator)
  139. {
  140.     for (MethodSymbol *method = base_method; method; method = method -> next_method)
  141.     {
  142. assert(method -> IsTyped());
  143.         if (method -> NumFormalParameters() == method_declarator -> NumFormalParameters())
  144.         {
  145.             int i;
  146.             for (i = method -> NumFormalParameters() - 1; i >= 0; i--)
  147.             {
  148.                 AstFormalParameter *parameter = method_declarator -> FormalParameter(i);
  149.                 if (method -> FormalParameter(i) -> Type() != parameter -> parameter_symbol -> Type())
  150.                     break;
  151.             }
  152.             if (i < 0)
  153.                 return method;
  154.         }
  155.     }
  156.  
  157.     return(MethodSymbol *)  NULL;
  158. }
  159.  
  160.  
  161. void TypeSymbol::ProcessTypeHeaders()
  162. {
  163.     AstClassDeclaration *class_declaration = declaration -> ClassDeclarationCast();
  164.  
  165.     if (class_declaration)
  166.          semantic_environment -> sem -> ProcessTypeHeaders(class_declaration);
  167.     else semantic_environment -> sem -> ProcessTypeHeaders((AstInterfaceDeclaration *) declaration);
  168. }
  169.  
  170. void TypeSymbol::ProcessMembers()
  171. {
  172.     AstClassDeclaration *class_declaration = declaration -> ClassDeclarationCast();
  173.  
  174.     if (class_declaration)
  175.          semantic_environment -> sem -> ProcessMembers(class_declaration -> semantic_environment, class_declaration -> class_body);
  176.     else semantic_environment -> sem -> ProcessMembers((AstInterfaceDeclaration *) declaration);
  177. }
  178.  
  179. void TypeSymbol::CompleteSymbolTable()
  180. {
  181.     AstClassDeclaration *class_declaration = declaration -> ClassDeclarationCast();
  182.  
  183.     if (class_declaration)
  184.          semantic_environment -> sem -> CompleteSymbolTable(class_declaration -> semantic_environment,
  185.                                                             class_declaration -> identifier_token, class_declaration -> class_body);
  186.     else semantic_environment -> sem -> CompleteSymbolTable((AstInterfaceDeclaration *) declaration);
  187. }
  188.  
  189.  
  190. void TypeSymbol::ProcessExecutableBodies()
  191. {
  192.     AstClassDeclaration *class_declaration = declaration -> ClassDeclarationCast();
  193.  
  194.     if (class_declaration)
  195.          semantic_environment -> sem -> ProcessExecutableBodies(class_declaration -> semantic_environment,
  196.                                                                 class_declaration -> class_body);
  197.     else semantic_environment -> sem -> ProcessExecutableBodies((AstInterfaceDeclaration *) declaration);
  198. }
  199.  
  200.  
  201. void TypeSymbol::RemoveCompilationReferences()
  202. {
  203.     if (semantic_environment)
  204.     {
  205.         semantic_environment = NULL;
  206.         declaration = NULL;
  207.  
  208.         //
  209.         // TODO: What else needs to be reset?
  210.         //
  211.         if (table)
  212.         {
  213.             for (int i = 0; i < table -> NumVariableSymbols(); i++)
  214.                 table -> VariableSym(i) -> declarator = NULL;
  215.  
  216.             for (int j = 0; j < table -> NumMethodSymbols(); j++)
  217.                 table -> MethodSym(j) -> method_or_constructor_declaration = NULL;
  218.  
  219.             for (int k = 0; k < table -> NumTypeSymbols(); k++)
  220.                 table -> TypeSym(k) -> declaration = NULL;
  221.  
  222.             for (int l = 0; l < table -> NumAnonymousSymbols(); l++)
  223.                 table -> AnonymousSym(l) -> declaration = NULL;
  224.         }
  225.     }
  226.  
  227.     return;
  228. }
  229.  
  230.  
  231. TypeSymbol *TypeSymbol::GetArrayType(Semantic *sem, int num_dimensions_)
  232. {
  233.     if (num_dimensions_ == 0)
  234.         return this;
  235.     if (num_dimensions_ < NumArrays())
  236.         return Array(num_dimensions_);
  237.  
  238.     if (NumArrays() == 0)
  239.         AddArrayType(this);
  240.  
  241.     TypeSymbol *previous_array_type = Array(array -> Length() - 1);
  242.     wchar_t *name = new wchar_t[this -> ExternalNameLength() + (num_dimensions_ * 2) + 1];
  243.     wcscpy(name, previous_array_type -> ExternalName());
  244.  
  245.     for (int num = array -> Length(), len = previous_array_type -> ExternalNameLength() + 2;
  246.          num <= num_dimensions_;
  247.          num++, len = len + 2)
  248.     {
  249.         wcscat(name, StringConstant::US__LB__RB_);
  250.         NameSymbol *name_sym = sem -> control.FindOrInsertName(name, len);
  251.  
  252.         AccessFlags acc_flags;
  253.         acc_flags.SetACC_PUBLIC();
  254.         acc_flags.SetACC_FINAL();
  255.  
  256.         TypeSymbol *type = new TypeSymbol(name_sym);
  257.  
  258.         type -> MarkHeaderProcessed();
  259.         type -> MarkConstructorMembersProcessed();
  260.         type -> MarkMethodMembersProcessed();
  261.         type -> MarkFieldMembersProcessed();
  262.         type -> MarkLocalClassProcessingCompleted();
  263.         type -> MarkSourceNoLongerPending();
  264.         type -> outermost_type = type;
  265.  
  266.         type -> SetFlags(acc_flags);
  267.         type -> super = sem -> control.Object();
  268.         //
  269.         // All arrays implement the interfaces java.io.Serializable and
  270.         // java.io.Cloneable
  271.         //
  272.         if (sem -> control.option.one_one)
  273.             type -> AddInterface(sem -> control.Serializable());
  274.         type -> AddInterface(sem -> control.Cloneable());
  275.         type -> base_type = this;
  276.         type -> num_dimensions = num;
  277.         type -> SetOwner(this -> ContainingPackage());
  278.         type -> table = new SymbolTable(3); // only 2 elements will be added to this table
  279.         type -> SetSignature(sem -> control);
  280.  
  281.         MethodSymbol *method = type -> InsertMethodSymbol(sem -> control.clone_name_symbol);
  282.         method -> SetType(sem -> control.Object());
  283.         method -> SetContainingType(type);
  284.         method -> SetFlags(acc_flags);
  285.         method -> SetBlockSymbol(new BlockSymbol(1)); // the associated symbol table will remain empty
  286.  
  287.         VariableSymbol *symbol = type -> InsertVariableSymbol(sem -> control.length_name_symbol);
  288.         symbol -> SetFlags(acc_flags);
  289.         symbol -> SetOwner(type);
  290.         symbol -> SetType(sem -> control.int_type);
  291.  
  292.         type -> CompressSpace(); // space optimization
  293.  
  294.         AddArrayType(type);
  295.     }
  296.  
  297.     delete [] name;
  298.     return Array(num_dimensions_);
  299. }
  300.  
  301. void TypeSymbol::SetLocation()
  302. {
  303.     if (! declaration)
  304.         file_location = new FileLocation(file_symbol);
  305.     else
  306.     {
  307.         AstClassDeclaration *class_declaration = declaration -> ClassDeclarationCast();
  308.         AstInterfaceDeclaration *interface_declaration = declaration -> InterfaceDeclarationCast();
  309.  
  310.         file_location = new FileLocation(semantic_environment -> sem -> lex_stream,
  311.                                          (class_declaration
  312.                                                ? class_declaration -> identifier_token
  313.                                                : (interface_declaration
  314.                                                            ? interface_declaration -> identifier_token
  315.                                                            : ((AstClassInstanceCreationExpression *) declaration)
  316.                                                                                            -> class_body_opt -> left_brace_token)));
  317.     }
  318.  
  319.     return;
  320. }
  321.  
  322.  
  323. void TypeSymbol::SetSignature(Control &control)
  324. {
  325.     if (this -> num_dimensions > 0)
  326.     {
  327.         char *type_signature;
  328.         TypeSymbol *subtype = this -> ArraySubtype();
  329.         int signature_len = strlen(subtype -> SignatureString()) + 1; // +1 for '['
  330.         type_signature = new char[signature_len + 1];                  // +1 for '\0'
  331.         type_signature[0] = U_LEFT_BRACKET;
  332.         strcpy(type_signature + 1, subtype -> SignatureString());
  333.         this -> signature = control.Utf8_pool.FindOrInsert(type_signature, signature_len);
  334.         this -> fully_qualified_name = this -> signature;
  335.         delete [] type_signature;
  336.     }
  337.     else
  338.     {
  339.         wchar_t *package_name = this -> ContainingPackage() -> PackageName();
  340.         wchar_t *type_name = this -> ExternalName();
  341.  
  342.         int len = this -> ContainingPackage() -> PackageNameLength() +
  343.                   this -> ExternalNameLength() + 4; // +1 for 'L' +1 for '/' +1 for ';' +1 for '\0'
  344.         wchar_t *type_signature = new wchar_t[len];
  345.         wcscpy(type_signature, StringConstant::US_L);
  346.         if (this -> ContainingPackage() -> PackageNameLength() > 0 && wcscmp(package_name, StringConstant::US__DO_) != 0)
  347.         {
  348.             wcscat(type_signature, package_name);
  349.             wcscat(type_signature, StringConstant::US__SL_);
  350.         }
  351.         wcscat(type_signature, type_name);
  352.         this -> fully_qualified_name = control.ConvertUnicodeToUtf8(type_signature + 1); // +1 to skip the initial L'L'
  353.  
  354.         wcscat(type_signature, StringConstant::US__SC_); 
  355.         this -> signature = control.ConvertUnicodeToUtf8(type_signature);
  356.  
  357.         delete [] type_signature;
  358.     }
  359.  
  360.     return;
  361. }
  362.  
  363.  
  364. int SymbolTable::primes[] = {DEFAULT_HASH_SIZE, 101, 401, MAX_HASH_SIZE};
  365.  
  366. void SymbolTable::Rehash()
  367. {
  368.     hash_size = primes[++prime_index];
  369.  
  370.     delete [] base;
  371.     base = (Symbol **) memset(new Symbol *[hash_size], 0, hash_size * sizeof(Symbol *));
  372.  
  373.     int k;
  374.     for (k = 0; k < NumTypeSymbols(); k++)
  375.     {
  376.         TypeSymbol *symbol = TypeSym(k);
  377.         int i = symbol -> name_symbol -> index % hash_size;
  378.         symbol -> next = base[i];
  379.         base[i] = symbol;
  380.     }
  381.  
  382.     for (k = 0; k < NumMethodSymbols(); k++)
  383.     {
  384.         MethodSymbol *symbol = MethodSym(k);
  385.         if (symbol -> next != symbol) // not an overload
  386.         {
  387.             int i = symbol -> name_symbol -> index % hash_size;
  388.             symbol -> next = base[i];
  389.             base[i] = symbol;
  390.         }
  391.     }
  392.  
  393.     for (k = 0; k < NumVariableSymbols(); k++)
  394.     {
  395.         VariableSymbol *symbol = VariableSym(k);
  396.         int i = symbol -> name_symbol -> index % hash_size;
  397.         symbol -> next = base[i];
  398.         base[i] = symbol;
  399.     }
  400.  
  401.     for (k = 0; k < NumOtherSymbols(); k++)
  402.     {
  403.         Symbol *symbol = OtherSym(k);
  404.  
  405.         if (! symbol -> BlockCast())
  406.         {
  407.             int i = symbol -> Identity() -> index % hash_size;
  408.             symbol -> next = base[i];
  409.             base[i] = symbol;
  410.         }
  411.     }
  412.  
  413.     return;
  414. }
  415.  
  416.  
  417. SymbolTable::SymbolTable(int hash_size_) : anonymous_symbol_pool(NULL),
  418.                                            type_symbol_pool(NULL),
  419.                                            method_symbol_pool(NULL),
  420.                                            variable_symbol_pool(NULL),
  421.                                            other_symbol_pool(NULL),
  422.                                            constructor(NULL)
  423. {
  424.     hash_size = (hash_size_ <= 0 ? 1 : hash_size_);
  425.  
  426.     prime_index = -1;
  427.     do
  428.     {
  429.         if (hash_size < primes[prime_index + 1])
  430.             break;
  431.         prime_index++;
  432.     } while (primes[prime_index] < MAX_HASH_SIZE);
  433.  
  434.     base = (Symbol **) memset(new Symbol *[hash_size], 0, hash_size * sizeof(Symbol *));
  435. }
  436.  
  437. SymbolTable::~SymbolTable()
  438. {
  439. /*
  440. int n;
  441. int num_slots = 0;
  442. int total = 0;
  443. for (n = 0; n < hash_size; n++)
  444. {
  445. int num = 0;
  446. for (Symbol *s = base[n]; s; s = s -> next)
  447.     num++;
  448. if (num > 0)
  449. {
  450. num_slots++;
  451. total += num;
  452. }
  453. }
  454.  
  455. if (num_slots > 0)
  456. {
  457. cout << "\nDestroying a symbol table with base size " << hash_size << " containing " << num_slots << " non-empty slots\n";
  458. for (n = 0; n < hash_size; n++)
  459. {
  460. int num = 0;
  461. for (Symbol *s = base[n]; s; s = s -> next)
  462.     num++;
  463. if (num > 0)
  464. cout << "    slot " << n << " contains " << num << " element(s)\n";
  465. }
  466. }
  467. if (hash_size < total)
  468.     total = total;
  469. */
  470.     for (int i = 0; i < NumAnonymousSymbols(); i++)
  471.         delete AnonymousSym(i);
  472.     delete anonymous_symbol_pool;
  473.     for (int j = 0; j < NumTypeSymbols(); j++)
  474.         delete TypeSym(j);
  475.     delete type_symbol_pool;
  476.     for (int k = 0; k < NumMethodSymbols(); k++)
  477.         delete MethodSym(k);
  478.     delete method_symbol_pool;
  479.     for (int l = 0; l < NumVariableSymbols(); l++)
  480.         delete VariableSym(l);
  481.     delete variable_symbol_pool;
  482.     for (int m = 0; m < NumOtherSymbols(); m++)
  483.         delete OtherSym(m);
  484.     delete other_symbol_pool;
  485.     delete [] base;
  486.  
  487.     return;
  488. }
  489.  
  490.  
  491. PackageSymbol::~PackageSymbol()
  492. {
  493.     delete [] package_name;
  494.     delete table;
  495. }
  496.  
  497.  
  498. void PackageSymbol::SetPackageName()
  499. {
  500.     this -> package_name_length = (owner ? owner -> PackageNameLength() + 1 : 0) + NameLength(); // +1 for '/'
  501.     this -> package_name = new wchar_t[package_name_length + 1]; // +1 for '\0'
  502.  
  503.     if (owner)
  504.     {
  505.         wcscpy(this -> package_name, owner -> PackageName());
  506.         wcscat(this -> package_name, StringConstant::US__SL_);
  507.     }
  508.     else this -> package_name[0] = U_NULL;
  509.     wcscat(this -> package_name, this -> Name());
  510.  
  511. assert(wcslen(this -> package_name) == this -> package_name_length);
  512.  
  513.     return;
  514. }
  515.  
  516.  
  517. TypeSymbol::TypeSymbol(NameSymbol *name_symbol_) : semantic_environment(NULL),
  518.                                                    declaration(NULL),
  519.                                                    file_symbol(NULL),
  520.                                                    file_location(NULL),
  521.                                                    name_symbol(name_symbol_),
  522.                                                    external_name_symbol(NULL),
  523.                                                    owner(NULL),
  524.                                                    outermost_type(NULL),
  525.                                                    super(NULL),
  526.                                                    base_type(NULL),
  527.                                                    index(CycleChecker::OMEGA),
  528.                                                    incremental_index(CycleChecker::OMEGA),
  529.                                                    status(0),
  530.                                                    local(NULL),
  531.                                                    non_local(NULL),
  532.                                                    supertypes_closure(NULL),
  533.                                                    subtypes(NULL),
  534.                                                    subtypes_closure(NULL),
  535.                                                    innertypes_closure(NULL),
  536.                                                    dependents(new SymbolSet()),
  537.                                                    parents(new SymbolSet()),
  538.                                                    dependents_closure(NULL),
  539.                                                    parents_closure(NULL),
  540.                                                    num_dimensions(0),
  541.                                                    class_literal_class(NULL),
  542.                                                    class_literal_method(NULL),
  543.                                                    static_initializer_method(NULL),
  544.                                                    block_initializer_method(NULL),
  545.                                                    signature(NULL),
  546.                                                    fully_qualified_name(NULL),
  547.                                                    class_literal_name(NULL),
  548.                                                    table(NULL),
  549.                                                    expanded_type_table(NULL),
  550.                                                    expanded_field_table(NULL),
  551.                                                    expanded_method_table(NULL),
  552.                                                    package(NULL),
  553.                                                    class_name(NULL),
  554.                                                    local_constructor_call_environments(NULL),
  555.                                                    private_access_methods(NULL),
  556.                                                    private_access_constructors(NULL),
  557.                                                    constructor_parameters(NULL),
  558.                                                    generated_constructors(NULL),
  559.                                                    enclosing_instances(NULL),
  560.                                                    class_literals(NULL),
  561.                                                    nested_types(NULL),
  562.                                                    interfaces(NULL),
  563.                                                    anonymous_types(NULL),
  564.                                                    array(NULL),
  565.                                                    nested_type_signatures(NULL)
  566. {
  567.     Symbol::_kind = TYPE;
  568. }
  569.  
  570.  
  571. TypeSymbol::~TypeSymbol()
  572. {
  573.     delete semantic_environment;
  574.     delete local;
  575.     delete non_local;
  576.     delete supertypes_closure;
  577.     delete subtypes;
  578.     delete subtypes_closure;
  579.     delete innertypes_closure;
  580.     delete dependents;
  581.     delete parents;
  582.     delete table;
  583.     delete expanded_type_table;
  584.     delete expanded_field_table;
  585.     delete expanded_method_table;
  586.     delete file_location;
  587.     delete [] class_name;
  588.     for (int i = 1; i < NumArrays(); i++)
  589.         delete Array(i);
  590.     for (int k = 0; k < NumNestedTypeSignatures(); k++)
  591.         delete [] NestedTypeSignature(k);
  592.     delete nested_type_signatures;
  593.  
  594.     delete local_constructor_call_environments;
  595.     delete private_access_methods;
  596.     delete private_access_constructors;
  597.     delete constructor_parameters;
  598.     delete generated_constructors;
  599.     delete enclosing_instances;
  600.     delete class_literals;
  601.     delete nested_types;
  602.     delete interfaces;
  603.     delete anonymous_types;
  604.     delete array;
  605. }
  606.  
  607. MethodSymbol::~MethodSymbol()
  608. {
  609.     for (int i = 0; i < NumThrowsSignatures(); i++)
  610.         delete [] ThrowsSignature(i);
  611.     delete throws_signatures;
  612.     delete formal_parameters;
  613.     delete throws;
  614.     delete initializer_constructors;
  615.  
  616.     delete block_symbol; // overload(s)
  617.     delete [] header;
  618. }
  619.  
  620.  
  621. BlockSymbol::BlockSymbol(int hash_size) : table(hash_size > 0 ? new SymbolTable(hash_size) : (SymbolTable *) NULL),
  622.                                           max_variable_index(-1),
  623.                                           try_variable_index(0)
  624. {
  625.     Symbol::_kind = BLOCK;
  626. }
  627.  
  628. BlockSymbol::~BlockSymbol()
  629. {
  630.     delete table;
  631. }
  632.  
  633. PathSymbol::PathSymbol(NameSymbol *name_symbol_) : name_symbol(name_symbol_),
  634.                                                    zipfile(NULL)
  635. {
  636.     Symbol::_kind = PATH;
  637. }
  638.  
  639. PathSymbol::~PathSymbol()
  640. {
  641.     if (zipfile)
  642.         delete zipfile;
  643. }
  644.  
  645.  
  646. DirectorySymbol::DirectorySymbol(NameSymbol *name_symbol_, Symbol *owner_) : name_symbol(name_symbol_),
  647.                                                                              owner(owner_),
  648.                                                                              mtime(0),
  649.                                                                              table(NULL),
  650.                                                                              directory_name(NULL),
  651.                                                                              entries(NULL)
  652. {
  653.     Symbol::_kind = _DIRECTORY;
  654. }
  655.  
  656.  
  657. DirectorySymbol::~DirectorySymbol()
  658. {
  659.     delete [] directory_name;
  660.     delete entries;
  661.     delete table;
  662. }
  663.  
  664. void DirectorySymbol::SetDirectoryName()
  665. {
  666.     PathSymbol *path_symbol = owner -> PathCast();
  667.     if (path_symbol)
  668.     {
  669.         if (strcmp(path_symbol -> Utf8Name(), StringConstant::U8S__DO_) == 0)
  670.         {
  671.             this -> directory_name_length = this -> Utf8NameLength();
  672.             this -> directory_name = new char[this -> directory_name_length + 1]; // +1 for '\0'
  673.  
  674.             strcpy(this -> directory_name, this -> Utf8Name());
  675.         }
  676.         else
  677.         {
  678.             this -> directory_name_length = path_symbol -> Utf8NameLength();
  679.             this -> directory_name = new char[this -> directory_name_length + 1]; // +1 for '\0'
  680.  
  681.             strcpy(this -> directory_name, path_symbol -> Utf8Name());
  682.         }
  683.     }
  684.     else
  685.     {
  686.         DirectorySymbol *owner_directory = owner -> DirectoryCast();
  687.         if (this -> Name()[this -> NameLength() - 1] == U_SLASH ||                     // An absolute file name ?
  688.             strcmp(owner_directory -> DirectoryName(), StringConstant::U8S__DO_) == 0) // or is the owner "." ?
  689.         {
  690.             this -> directory_name_length = this -> Utf8NameLength();
  691.             this -> directory_name = new char[this -> directory_name_length + 1];  // +1 for '\0'
  692.             strcpy(this -> directory_name, this -> Utf8Name());
  693.         }
  694.         else
  695.         {
  696.             int owner_length = owner_directory -> DirectoryNameLength();
  697.             char *owner_name = owner_directory -> DirectoryName();
  698.             this -> directory_name_length = owner_length +
  699.                                             this -> Utf8NameLength() +
  700.                                             (owner_name[owner_length - 1] != U_SLASH ? 1 : 0); // +1 for '/'
  701.  
  702.             this -> directory_name = new char[this -> directory_name_length + 1]; // +1 for '\0'
  703.  
  704.             strcpy(this -> directory_name, owner_directory -> DirectoryName());
  705.             if (owner_name[owner_length - 1] != U_SLASH)
  706.                 strcat(this -> directory_name, StringConstant::U8S__SL_);
  707.             strcat(this -> directory_name, this -> Utf8Name());
  708.         }
  709.     }
  710.  
  711. assert(strlen(this -> directory_name) == this -> directory_name_length);
  712.  
  713.     return;
  714. }
  715.  
  716.  
  717. void DirectorySymbol::ResetDirectory()
  718. {
  719. assert(! this -> IsZip());
  720.  
  721.     //
  722.     // TODO: the stat function does not work for directories in that the "modified" time stamp associated
  723.     // with a directory is not updated when a file contained in the directory is changed.
  724.     // For now, we always reread the directory.
  725.     //
  726.     //    struct stat status;
  727.     //    if ((::SystemStat(this -> DirectoryName(), &status) == 0) && status.st_mtime > mtime)
  728.     //    {
  729.     //        this -> mtime = status.st_mtime;
  730.     //
  731.     //        delete this -> entries;
  732.     //        this -> entries = new DirectoryTable();
  733.     //
  734.     //        ReadDirectory();
  735.     //    }
  736.     //
  737.     //    else if (! entries) // if we cannot read the directory, allocate a default directory.
  738.     //        this -> entries = new DirectoryTable();
  739.     //
  740.  
  741.         delete this -> entries;
  742.         this -> entries = new DirectoryTable();
  743.  
  744.         ReadDirectory();
  745.  
  746.     return;
  747. }
  748.  
  749.  
  750. void DirectorySymbol::ReadDirectory()
  751. {
  752. #if defined(UNIX_FILE_SYSTEM) || defined(AMIGAOS_FILE_SYSTEM)
  753.     DIR *directory = opendir(this -> DirectoryName());
  754.     if (directory)
  755.     {
  756.         for (dirent *entry = readdir(directory); entry; entry = readdir(directory))
  757.         {
  758.             int length = strlen(entry -> d_name);
  759.  
  760.             //
  761.             // Check if the file is a java source, a java class file or a subdirectory.
  762.             // Since packages cannot start with '.', we skip all files that start with 
  763.             // a dot. That includes this directory "." and its parent ".."
  764.             //
  765.             if ((length > FileSymbol::java_suffix_length &&
  766.                  FileSymbol::IsJavaSuffix(&entry -> d_name[length - FileSymbol::java_suffix_length]))  ||
  767.                 (length > FileSymbol::class_suffix_length &&
  768.                  FileSymbol::IsClassSuffix(&entry -> d_name[length - FileSymbol::class_suffix_length])) ||
  769.                 ((Case::Index(entry -> d_name, U_DOT) < 0) && SystemIsDirectory(entry -> d_name)))
  770.                 entries -> InsertEntry((DirectorySymbol *) this, entry -> d_name, length);
  771.         }
  772.         closedir(directory);
  773.     }
  774. #elif defined(WIN32_FILE_SYSTEM)
  775.     char *directory_name = new char[this -> DirectoryNameLength() + 3]; // +2 for "/*" +1 for '\0'
  776.     strcpy(directory_name, this -> DirectoryName());
  777.     if (directory_name[this -> DirectoryNameLength() - 1] != U_SLASH)
  778.         strcat(directory_name, StringConstant::U8S__SL_);
  779.     strcat(directory_name, StringConstant::U8S__ST_);
  780.  
  781.     WIN32_FIND_DATA entry;
  782.     HANDLE file_handle = FindFirstFile(directory_name, &entry);
  783.     if (file_handle != INVALID_HANDLE_VALUE)
  784.     {
  785.         do
  786.         {
  787.             int length = strlen(entry.cFileName);
  788.  
  789.             //
  790.             // Check if the file is a java source, a java class file or a subdirectory.
  791.             // Since packages cannot start with '.', we skip all files that start with 
  792.             // a dot. That includes this directory "." and its parent ".."
  793.             //
  794.             bool is_java  = (length > FileSymbol::java_suffix_length &&
  795.                              FileSymbol::IsJavaSuffix(&entry.cFileName[length - FileSymbol::java_suffix_length])),
  796.                  is_class = (length > FileSymbol::class_suffix_length &&
  797.                              FileSymbol::IsClassSuffix(&entry.cFileName[length - FileSymbol::class_suffix_length]));
  798.  
  799.             if (is_java ||
  800.                 is_class ||
  801.                 (entry.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY && Case::Index(entry.cFileName, U_DOT) < 0))
  802.             {
  803.                 char *clean_name = new char[length + 1];
  804.                 for (int i = 0; i < length; i++)
  805.                     clean_name[i] = (entry.cFileName[i] == U_BACKSLASH ? U_SLASH : entry.cFileName[i]);
  806.                 if (is_java)
  807.                      strcpy(&clean_name[length - FileSymbol::java_suffix_length], FileSymbol::java_suffix);
  808.                 else if (is_class)
  809.                      strcpy(&clean_name[length - FileSymbol::class_suffix_length], FileSymbol::class_suffix);
  810.                 DirectoryEntry *entry = entries -> InsertEntry((DirectorySymbol *) this, clean_name, length);
  811.                 if (! is_java)
  812.                     entries -> InsertCaseInsensitiveEntry(entry);
  813.                 delete [] clean_name;
  814.             }
  815.         } while (FindNextFile(file_handle, &entry));
  816.         FindClose(file_handle);
  817.     }
  818.  
  819.     delete [] directory_name;
  820. #endif
  821.  
  822.     return;
  823. }
  824.  
  825.  
  826. DirectorySymbol *FileSymbol::OutputDirectory()
  827. {
  828.     return (output_directory ? output_directory : output_directory = Control::GetOutputDirectory(this));
  829. }
  830.  
  831.  
  832. void FileSymbol::SetFileName()
  833. {
  834.     PathSymbol *path_symbol = this -> PathSym();
  835.     char *directory_name = directory_symbol -> DirectoryName();
  836.     int directory_name_length = directory_symbol -> DirectoryNameLength();
  837.     bool dot_directory = (strcmp(directory_name, StringConstant::U8S__DO_) == 0);
  838.     this -> file_name_length = (dot_directory ? 0 : directory_name_length) +
  839.                                this -> Utf8NameLength()   +
  840.                                (path_symbol -> IsZip() // For zip files we need "()" for regular directory, we need 1 '/'
  841.                                              ? 2
  842.                                              : (dot_directory || directory_name[directory_name_length - 1] == U_SLASH ? 0 : 1)) +
  843.                                (kind == JAVA ? java_suffix_length : class_suffix_length);
  844.  
  845.     file_name = new char[file_name_length + 1]; // +1 for '\0'
  846.     if (dot_directory)
  847.          file_name[0] = U_NULL;
  848.     else
  849.     {
  850.         strcpy(file_name, directory_symbol -> DirectoryName());
  851.         if (path_symbol -> IsZip())
  852.              strcat(file_name, StringConstant::U8S__LP_);
  853.         else if (directory_name[directory_name_length - 1] != U_SLASH)
  854.              strcat(file_name, StringConstant::U8S__SL_);
  855.     }
  856.     strcat(file_name, this -> Utf8Name());
  857.     strcat(file_name, kind == JAVA ? FileSymbol::java_suffix : FileSymbol::class_suffix);
  858.     if (path_symbol -> IsZip())
  859.         strcat(file_name, StringConstant::U8S__RP_);
  860.  
  861. assert(strlen(this -> file_name) == this -> file_name_length);
  862.  
  863.     return;
  864. }
  865.  
  866.  
  867. void FileSymbol::CleanUp()
  868. {
  869.     delete lex_stream;
  870.     lex_stream = NULL;
  871.  
  872.     if (compilation_unit)
  873.     {
  874.         delete compilation_unit -> ast_pool;
  875.         compilation_unit = NULL;
  876.     }
  877.  
  878.     delete semantic;
  879.     semantic = NULL;
  880.  
  881.     return;
  882. }
  883.  
  884.  
  885. void TypeSymbol::SetClassName()
  886. {
  887.     int length;
  888.  
  889.     if (semantic_environment -> sem -> control.option.directory)
  890.     {
  891.         DirectorySymbol *output_directory = file_symbol -> OutputDirectory();
  892.         int directory_length = output_directory -> DirectoryNameLength();
  893.         char *directory_name = output_directory -> DirectoryName();
  894.         length = directory_length + this -> ExternalUtf8NameLength() + FileSymbol::class_suffix_length + 1; // +1 for /
  895.         class_name = new char[length + 1]; // +1 for '\0'
  896.  
  897.         strcpy(class_name, directory_name);
  898.  
  899.         if (directory_name[directory_length - 1] != U_SLASH)
  900.             strcat(class_name, StringConstant::U8S__SL_);
  901.     }
  902.     else
  903.     {
  904.         char *file_name = semantic_environment -> sem -> lex_stream -> FileName();
  905.         int n;
  906.         for (n = semantic_environment -> sem -> lex_stream -> FileNameLength() - 1; n >= 0; n--)
  907.         {
  908.             if (file_name[n] == U_SLASH)
  909.                 break;
  910.         }
  911.         n++;
  912.  
  913.         length = n + this -> ExternalUtf8NameLength() + FileSymbol::class_suffix_length;
  914.         class_name = new char[length + 1]; // +1 for '\0'
  915.         strncpy(class_name, file_name, n);
  916.         class_name[n] = U_NULL;
  917.     }
  918.  
  919.     strcat(class_name, ExternalUtf8Name());
  920.     strcat(class_name, FileSymbol::class_suffix);
  921.  
  922. assert(strlen(this -> class_name) <= length);
  923.  
  924.     return;
  925. }
  926.  
  927.  
  928. void TypeSymbol::ProcessNestedTypeSignatures(Semantic *sem, LexStream::TokenIndex tok)
  929. {
  930.     for (int i = 0; i < NumNestedTypeSignatures(); i++)
  931.     {
  932.         int length = strlen(NestedTypeSignature(i));
  933.         wchar_t *nested_class_name = new wchar_t[length + 1];
  934.         sem -> ConvertUtf8ToUnicode(nested_class_name, NestedTypeSignature(i), length);
  935.         NameSymbol *name_symbol = sem -> control.FindOrInsertName(nested_class_name, length);
  936.  
  937.         delete [] nested_class_name;
  938.         delete [] NestedTypeSignature(i);
  939.  
  940.         sem -> ProcessNestedType(this, name_symbol, tok);
  941.     }
  942.  
  943.     delete nested_type_signatures;
  944.     nested_type_signatures = NULL;
  945.  
  946.     return;
  947. }
  948.  
  949.  
  950. void MethodSymbol::ProcessMethodThrows(Semantic *sem, LexStream::TokenIndex tok)
  951. {
  952.     if (throws_signatures)
  953.     {
  954. assert(sem);
  955.         //
  956.         // Process throws clause
  957.         //
  958.         for (int i = 0; i < NumThrowsSignatures(); i++)
  959.         {
  960.             int length = strlen(ThrowsSignature(i));
  961.             wchar_t *type_name = new wchar_t[length + 1];
  962.             sem -> ConvertUtf8ToUnicode(type_name, ThrowsSignature(i), length);
  963.             this -> AddThrows(sem -> ReadType(this -> containing_type, type_name, tok));
  964.             delete [] type_name;
  965.             delete [] ThrowsSignature(i);
  966.         }
  967.  
  968.         delete throws_signatures;
  969.         throws_signatures = NULL;
  970.     }
  971.  
  972.     return;
  973. }
  974.  
  975.  
  976. void MethodSymbol::SetSignature(Control &control, VariableSymbol *this0_variable)
  977. {
  978.     int len = 2 + strlen(this -> Type() -> SignatureString()); // +1 for '(' +1 for ')'
  979.  
  980.     if (this0_variable)
  981.         len += strlen(this0_variable -> Type() -> SignatureString());
  982.     for (int i = 0; i < this -> NumFormalParameters(); i++)
  983.     {
  984.         TypeSymbol *formal_type = this -> FormalParameter(i) -> Type();
  985.         len += strlen(formal_type -> SignatureString());
  986.     }
  987.         
  988.     char *method_signature = new char[len + 1]; // +1 for '\0'
  989.     method_signature[0] = U_LEFT_PARENTHESIS;
  990.     int k = 1;
  991.     if (this0_variable)
  992.     {
  993.         for (char *str = this0_variable -> Type() -> SignatureString(); *str; str++, k++)
  994.             method_signature[k] = *str;
  995.     }
  996.     for (int j = 0; j < this -> NumFormalParameters(); j++)
  997.     {
  998.         TypeSymbol *formal_type = this -> FormalParameter(j) -> Type();
  999.         for (char *str = formal_type -> SignatureString(); *str; str++, k++)
  1000.             method_signature[k] = *str;
  1001.     }
  1002.     method_signature[k++] = U_RIGHT_PARENTHESIS;
  1003.     for (char *str = this -> Type() -> SignatureString(); *str; str++, k++)
  1004.          method_signature[k] = *str;
  1005.     method_signature[k] = U_NULL;
  1006.  
  1007.     this -> signature = control.Utf8_pool.FindOrInsert(method_signature, len);
  1008.  
  1009.     delete [] method_signature;
  1010.  
  1011.     return;
  1012. }
  1013.  
  1014.  
  1015. void MethodSymbol::ProcessMethodSignature(Semantic *sem, LexStream::TokenIndex token_location)
  1016. {
  1017.     if (! this -> type_)
  1018.     {
  1019. assert(sem);
  1020.         int num_parameters = 0;
  1021.         char *signature = this -> SignatureString();
  1022.         signature++; // +1 to skip initial '('
  1023.  
  1024.         //
  1025.         // For the constructor of an inner type, skip the "this$0" argument.
  1026.         //
  1027.         if (this -> containing_type -> IsInner() && this -> Identity() == sem -> control.init_name_symbol)
  1028.         {
  1029.             if (*signature != U_RIGHT_PARENTHESIS)
  1030.             {
  1031.                 //
  1032.                 // Move to next signature
  1033.                 //
  1034.                 char *str;
  1035.                 for (str = signature; *str == U_LEFT_BRACKET; str++)
  1036.                     ;
  1037.                 if (*str == U_L)
  1038.                 {
  1039.                     for (str++; *str != U_SEMICOLON; str++)
  1040.                         ;
  1041.                 }
  1042.  
  1043.                 int len = str - signature + 1;
  1044.                 signature += len; // make signature point to next type
  1045.             }
  1046.         }
  1047.  
  1048.         while (*signature != U_RIGHT_PARENTHESIS)
  1049.         {
  1050.             //
  1051.             // Make up a name for each parameter... Recall that for an inner class we need to skip the this$0 parameter
  1052.             //
  1053.             NameSymbol *name_symbol = sem -> control.MakeParameter(++num_parameters);
  1054.             VariableSymbol *symbol = new VariableSymbol(name_symbol);
  1055.             symbol -> SetType(sem -> ProcessSignature(this -> containing_type, signature, token_location));
  1056.             symbol -> MarkComplete();
  1057.             this -> AddFormalParameter(symbol);
  1058.  
  1059.             //
  1060.             // Move to next signature
  1061.             //
  1062.             char *str;
  1063.             for (str = signature; *str == U_LEFT_BRACKET; str++)
  1064.                 ;
  1065.             if (*str == U_L)
  1066.             {
  1067.                 for (str++; *str != U_SEMICOLON; str++)
  1068.                     ;
  1069.             }
  1070.  
  1071.             int len = str - signature + 1;
  1072.             signature += len; // make signature point to next type
  1073.         }
  1074.         signature++; // skip L')'
  1075.  
  1076.         //
  1077.         // Now set the type of the method.
  1078.         //
  1079.         this -> SetType(sem -> ProcessSignature(this -> containing_type, signature, token_location));
  1080.  
  1081.         //
  1082.         // Create a symbol table for this method for consistency... and in order
  1083.         // to release the space used by the variable paramaters later.
  1084.         //
  1085.         BlockSymbol *block_symbol = new BlockSymbol(num_parameters);
  1086.         for (int k = 0; k < num_parameters; k++)
  1087.             block_symbol -> InsertVariableSymbol((*this -> formal_parameters)[k]);
  1088.         block_symbol -> CompressSpace(); // space optimization
  1089.         this -> SetBlockSymbol(block_symbol);
  1090.     }
  1091.  
  1092.     return;
  1093. }
  1094.  
  1095.  
  1096. void MethodSymbol::CleanUp()
  1097. {
  1098.     BlockSymbol *block_symbol = new BlockSymbol(this -> NumFormalParameters());
  1099.  
  1100.     //
  1101.     // Make a copy of each parameter into the new pared-down symbol table and
  1102.     // fix the FormalParameter information to identify the new symbol.
  1103.     //
  1104.     for (int k = 0; k < this -> NumFormalParameters(); k++)
  1105.     {
  1106.         VariableSymbol *formal_parameter = (*formal_parameters)[k],
  1107.                        *symbol = block_symbol -> InsertVariableSymbol(formal_parameter -> Identity());
  1108.         symbol -> SetType(formal_parameter -> Type());
  1109.         symbol -> MarkComplete();
  1110.         (*formal_parameters)[k] = symbol;
  1111.     }
  1112.  
  1113.     //
  1114.     // Destroy the old symbol and replace it by the new one.
  1115.     //
  1116.     delete this -> block_symbol;
  1117.     block_symbol -> CompressSpace(); // space optimization
  1118.     this -> SetBlockSymbol(block_symbol);
  1119.  
  1120.     this -> method_or_constructor_declaration = NULL; // remove reference to Ast structure
  1121.  
  1122.     return;
  1123. }
  1124.  
  1125.  
  1126. void VariableSymbol::ProcessVariableSignature(Semantic *sem, LexStream::TokenIndex token_location)
  1127. {
  1128.     if (! this -> type_)
  1129.     {
  1130. assert(sem);
  1131.         this -> SetType(sem -> ProcessSignature((TypeSymbol *) owner, signature_string, token_location));
  1132.     }
  1133.  
  1134.     return;
  1135. }
  1136.  
  1137.  
  1138. bool TypeSymbol::IsNestedIn(TypeSymbol *type)
  1139. {
  1140.     for (SemanticEnvironment *env = this -> semantic_environment; env != NULL; env = env -> previous)
  1141.     {
  1142.         if (env -> Type() == type)
  1143.              return true;
  1144.     }
  1145.  
  1146.     return false;
  1147. }
  1148.  
  1149.  
  1150. bool TypeSymbol::CanAccess(TypeSymbol *type)
  1151. {
  1152. assert(semantic_environment);
  1153.     SemanticEnvironment *env = this -> semantic_environment;
  1154.     //
  1155.     // Note that this case is only possible in the current environment (i.e., it is not recursively applicable)
  1156.     // as it is not possible to declare an inner class (even an anonymous one) within an explicit
  1157.     // constructor invocation. This is the case precisely because of the unavailability of the "this"
  1158.     // which one would need to pass to the inner class in question. See comment below...
  1159.     //
  1160.     if (env -> explicit_constructor_invocation && env -> explicit_constructor_invocation -> SuperCallCast())
  1161.     {
  1162.         //
  1163.         // If we are processing a super call statement in the constructor of an inner class then
  1164.         // we have access to the this$0 (passed to the constructor of the inner class as parameter) but
  1165.         // not to the "this" of the inner class in question, unless it is static.
  1166.         //
  1167.         if (this -> IsSubclass(type))
  1168.             return this -> ACC_STATIC(); // "this" class is accessible only if it is static.
  1169.         if (this -> IsInner())
  1170.         {
  1171.             if (this -> ContainingType() -> IsSubclass(type))
  1172.                 return true;
  1173.             env = env -> previous; // skip "this" type.
  1174.         }
  1175.     }
  1176.  
  1177.     for (; env != NULL; env = env -> previous)
  1178.     {
  1179.         if (env -> StaticRegion()) // are we in a static environment?
  1180.              break;
  1181.         else if (env -> Type() -> IsSubclass(type)) // then, check if we reached the type in question or one of its superclasses;
  1182.              return true;
  1183.         else if (env -> Type() -> ACC_STATIC())     // next, check whether or not the current type is static...
  1184.              break;
  1185.     }
  1186.  
  1187.     return false;
  1188. }
  1189.  
  1190.  
  1191. //
  1192. // Given two types T and T2 in different packages, the type T has protected
  1193. // access to T2 iff T or any class in which T is lexically enclosed is a subclass
  1194. // of T2 or of some other type T3 that lexically encloses T2.
  1195. //
  1196. // Of course, T2 and all its enclosing classes, if any, must have been declared
  1197. // either public or protected, otherwise they could not be eligible as a superclass
  1198. // candidate. We do not (and need not) check for that condition here.
  1199. //
  1200. bool TypeSymbol::HasProtectedAccessTo(TypeSymbol *target_type)
  1201. {
  1202. assert(semantic_environment);
  1203.     
  1204.     for (SemanticEnvironment *env = this -> semantic_environment; env != NULL; env = env -> previous)
  1205.     {
  1206.         TypeSymbol *main_type = env -> Type();
  1207.         for (TypeSymbol *type = target_type; type; type = type -> owner -> TypeCast())
  1208.         {
  1209.             if (main_type -> IsSubclass(type)) // then, check if we reached the type in question or one of its superclasses;
  1210.                 return true;
  1211.         }
  1212.     }
  1213.  
  1214.     return false;
  1215. }
  1216.  
  1217.  
  1218. inline NameSymbol *TypeSymbol::GetThisName(Control &control, int n)
  1219. {
  1220.     wchar_t info[12],
  1221.             *str = &info[11];
  1222.     *str = U_NULL;
  1223.     int num = n;
  1224.     do
  1225.     {
  1226.         *--str = (U_0 + num % 10);
  1227.         num /= 10;
  1228.     } while (num != 0);
  1229.  
  1230.     int length = wcslen(StringConstant::US__this_DOLLAR) + (&info[11] - str);
  1231.     wchar_t *name = new wchar_t[length + 1]; // +1 for '\0';
  1232.     wcscpy(name, StringConstant::US__this_DOLLAR);
  1233.     wcscat(name, str);
  1234.     NameSymbol *name_symbol = control.FindOrInsertName(name, length);
  1235.  
  1236.     delete [] name;
  1237.  
  1238.     return name_symbol;
  1239. }
  1240.  
  1241.  
  1242. VariableSymbol *TypeSymbol::InsertThis(int n)
  1243. {
  1244. assert(IsInner());
  1245.     Control &control = semantic_environment -> sem -> control;
  1246.     VariableSymbol *variable_symbol = NULL;
  1247.  
  1248.     if (n == 0)
  1249.     {
  1250. assert(NumConstructorParameters() == 0); // no local shadows and no this$0 !!!
  1251. assert(NumEnclosingInstances() == 0);
  1252.         //
  1253.         // Create a this0 pointer for an inner class.
  1254.         //
  1255.         variable_symbol = InsertVariableSymbol(control.this0_name_symbol);
  1256.         variable_symbol -> MarkSynthetic();
  1257.         variable_symbol -> SetType(ContainingType());
  1258.         variable_symbol -> SetACC_PRIVATE();
  1259. //        variable_symbol -> SetACC_FINAL();
  1260.         variable_symbol -> SetOwner((TypeSymbol *) this);
  1261.         variable_symbol -> MarkComplete();
  1262.  
  1263.         AddConstructorParameter(variable_symbol);
  1264.         AddEnclosingInstance(variable_symbol); // must at least have this$0
  1265.     }
  1266.     else
  1267.     {
  1268. assert(NumEnclosingInstances() == n);
  1269.         //
  1270.         // Create a this$n pointer.
  1271.         //
  1272.         variable_symbol = InsertVariableSymbol(GetThisName(control, n));
  1273.         variable_symbol -> MarkSynthetic();
  1274.         variable_symbol -> SetType(EnclosingInstance(n - 1) -> Type() -> ContainingType());
  1275.         variable_symbol -> SetACC_PRIVATE();
  1276. //        variable_symbol -> SetACC_FINAL();
  1277.         variable_symbol -> SetOwner((TypeSymbol *) this);
  1278.         variable_symbol -> MarkComplete();
  1279.  
  1280.         AddEnclosingInstance(variable_symbol);
  1281.     }
  1282.  
  1283.     return variable_symbol;
  1284. }
  1285.  
  1286.  
  1287. TypeSymbol *TypeSymbol::FindOrInsertClassLiteralClass(LexStream::TokenIndex tok)
  1288. {
  1289.     Semantic *sem = semantic_environment -> sem;
  1290.     AstCompilationUnit *compilation_unit = sem -> compilation_unit;
  1291.     Control &control = sem -> control;
  1292.  
  1293. assert(this == outermost_type);
  1294.  
  1295.     if (! this -> class_literal_class)
  1296.     {
  1297.         AstClassInstanceCreationExpression *class_creation = compilation_unit -> ast_pool -> GenClassInstanceCreationExpression();
  1298.         class_creation -> base_opt      = NULL;
  1299.         class_creation -> dot_token_opt = 0;
  1300.         class_creation -> new_token = tok;
  1301.  
  1302.              AstSimpleName *ast_type= compilation_unit -> ast_pool -> GenSimpleName(tok);
  1303.  
  1304.         class_creation -> class_type = compilation_unit -> ast_pool -> GenTypeExpression(ast_type);
  1305.         class_creation -> left_parenthesis_token  = tok;
  1306.         class_creation -> right_parenthesis_token = tok;
  1307.  
  1308.             AstClassBody *class_body = compilation_unit -> ast_pool -> GenClassBody();
  1309.             class_body -> left_brace_token = tok;
  1310.             class_body -> right_brace_token = tok;
  1311.  
  1312.         class_creation -> class_body_opt = class_body;
  1313.  
  1314.         TypeSymbol *class_literal_type = sem -> GetAnonymousType(class_creation, control.Object());
  1315.         (void) class_literal_type -> FindOrInsertClassLiteralMethod(control);
  1316.  
  1317.         sem -> AddDependence(class_literal_type, control.Class(), tok);
  1318.  
  1319.         this -> class_literal_class = class_literal_type;
  1320.     }
  1321.  
  1322.     return this -> class_literal_class;
  1323. }
  1324.  
  1325.  
  1326. MethodSymbol *TypeSymbol::FindOrInsertClassLiteralMethod(Control &control)
  1327. {
  1328.     if (! class_literal_method)
  1329.     {
  1330.         BlockSymbol *block_symbol = new BlockSymbol(1); // the associated symbol table will contain 1 element
  1331.         block_symbol -> max_variable_index = 0;
  1332.  
  1333.         NameSymbol *name_symbol = control.FindOrInsertName(StringConstant::US__class_DOLLAR,
  1334.                                                            wcslen(StringConstant::US__class_DOLLAR));
  1335.  
  1336.         class_literal_method = InsertMethodSymbol(name_symbol);
  1337.         class_literal_method -> SetType(control.Class());
  1338.         class_literal_method -> SetACC_STATIC();
  1339.         class_literal_method -> SetContainingType((TypeSymbol *) this);
  1340.         class_literal_method -> SetBlockSymbol(block_symbol);
  1341.  
  1342.             VariableSymbol *variable_symbol = block_symbol -> InsertVariableSymbol(control.MakeParameter(1));
  1343.             variable_symbol -> MarkSynthetic();
  1344.             variable_symbol -> SetType(control.String());
  1345.             variable_symbol -> SetOwner(class_literal_method);
  1346.             variable_symbol -> SetLocalVariableIndex(block_symbol -> max_variable_index++);
  1347.  
  1348.         class_literal_method -> AddFormalParameter(variable_symbol);
  1349.         class_literal_method -> SetSignature(control);
  1350.     }
  1351.  
  1352.     return class_literal_method;
  1353. }
  1354.  
  1355.  
  1356. Utf8LiteralValue *TypeSymbol::FindOrInsertClassLiteralName(Control &control)
  1357. {
  1358.     if (! class_literal_name)
  1359.     {
  1360.         int length = fully_qualified_name -> length;
  1361.         char *slashed_name = fully_qualified_name -> value;
  1362.         char *name = new char[length + 1];
  1363.         for (int i = 0; i < length; i++)
  1364.             name[i] = (slashed_name[i] == U_SLASH ? (wchar_t) U_DOT : slashed_name[i]);
  1365.         name[length] = U_NULL;
  1366.         class_literal_name = control.Utf8_pool.FindOrInsert(name, length);
  1367.         delete [] name;
  1368.     }
  1369.  
  1370.     return class_literal_name;
  1371. }
  1372.  
  1373.  
  1374. VariableSymbol *TypeSymbol::FindOrInsertClassLiteral(TypeSymbol *type)
  1375. {
  1376. assert(IsTopLevel() && (! type -> Primitive()));
  1377.     Semantic *sem = semantic_environment -> sem;
  1378.     Control &control = sem -> control;
  1379.  
  1380.     (void) this -> FindOrInsertClassLiteralMethod(control);
  1381.  
  1382.     (void) type -> FindOrInsertClassLiteralName(control);
  1383.  
  1384.     NameSymbol *name_symbol = NULL;
  1385.     char *signature = type -> SignatureString();
  1386.     if (signature[0] == U_LEFT_BRACKET) // an array?
  1387.     {
  1388.         int array_length = wcslen(StringConstant::US__array),
  1389.             length = strlen(signature) + array_length;
  1390.         wchar_t *name = new wchar_t[length + 1]; // +1 for '\0';
  1391.         wcscpy(name, StringConstant::US__array);
  1392.         int i,
  1393.             k;
  1394.         for (i = 0, k = array_length; signature[i] == U_LEFT_BRACKET; i++, k++)
  1395.             name[k] = U_DOLLAR;
  1396.         for (wchar_t ch = signature[i++]; ch && ch != U_SEMICOLON; ch = signature[i++])
  1397.             name[k++] = (ch == U_SLASH ? (wchar_t) U_DOLLAR : ch);
  1398.         name[k] = U_NULL;
  1399.         name_symbol = control.FindOrInsertName(name, k);
  1400.  
  1401.         delete [] name;
  1402.     }
  1403.     else if (signature[0] == U_L) // a reference type ?
  1404.     {
  1405.         int class_length = wcslen(StringConstant::US__class_DOLLAR),
  1406.             length = strlen(signature) + class_length;
  1407.  
  1408.         wchar_t *name = new wchar_t[length + 1]; // +1 for '\0';
  1409.         wcscpy(name, StringConstant::US__class_DOLLAR);
  1410.         int i = 0,
  1411.             k = class_length;
  1412.         for (wchar_t ch = signature[i++]; ch && ch != U_SEMICOLON; ch = signature[i++])
  1413.             name[k++] = (ch == U_SLASH ? (wchar_t) U_DOLLAR : ch);
  1414.         name[k] = U_NULL;
  1415.         name_symbol = control.FindOrInsertName(name, k);
  1416.  
  1417.         delete [] name;
  1418.     }
  1419.  
  1420.     VariableSymbol *variable_symbol = FindVariableSymbol(name_symbol);
  1421.     if (! variable_symbol)
  1422.     {
  1423.         variable_symbol = InsertVariableSymbol(name_symbol);
  1424.         variable_symbol -> MarkSynthetic();
  1425.         variable_symbol -> SetType(control.Class());
  1426.         variable_symbol -> SetACC_PRIVATE();
  1427.         variable_symbol -> SetACC_STATIC();
  1428.         variable_symbol -> SetOwner((TypeSymbol *) this);
  1429.         variable_symbol -> MarkComplete();
  1430.  
  1431.         AddClassLiteral(variable_symbol);
  1432.     }
  1433.  
  1434.     return variable_symbol;
  1435. }
  1436.  
  1437.  
  1438. VariableSymbol *TypeSymbol::FindOrInsertLocalShadow(VariableSymbol *local)
  1439. {
  1440. assert(this -> IsLocal());
  1441.     Control &control = semantic_environment -> sem -> control;
  1442.     VariableSymbol *variable = FindVariableSymbol(local -> Identity());
  1443.  
  1444.     //
  1445.     // For a local class, if it does not yet have a shadow for a local variable
  1446.     // that it needs access to, create one.
  1447.     //
  1448.     // Note that since this function is always invoked after the symbol
  1449.     // table for the type in question has been extended, the local shadow will
  1450.     // not appear in the expanded_field_table. Creating a shadow in the 
  1451.     // expanded_field_table as well would cut down on the number of calls to
  1452.     // this function. However, the reason why we don't create such a shadow is
  1453.     // that since the new symbol is assigned a new name on the fly, its
  1454.     // name_symbol will fall outside the range of the expanded field table in
  1455.     // question.
  1456.     //
  1457.     if (! variable)
  1458.     {
  1459.         variable = InsertVariableSymbol(local -> Identity());
  1460.         variable -> MarkSynthetic();
  1461.         variable -> accessed_local = local;
  1462.         variable -> SetType(local -> Type());
  1463.         variable -> SetACC_PRIVATE();
  1464. //        variable -> SetACC_FINAL();
  1465.         variable -> SetOwner((TypeSymbol *) this);
  1466.         variable -> MarkComplete();
  1467.  
  1468.         int length = 4 + local -> NameLength(); // +4 for val$
  1469.         wchar_t *external_name = new wchar_t[length + 1]; // +1 for '\0';
  1470.         wcscpy(external_name, StringConstant::US__val_DOLLAR);
  1471.         wcscat(external_name, local -> Name());
  1472.  
  1473.         variable -> SetExternalIdentity(control.FindOrInsertName(external_name, length));
  1474.         AddConstructorParameter(variable);
  1475.  
  1476.         delete [] external_name;
  1477.  
  1478.         for (int i = 0; i < NumGeneratedConstructors(); i++)
  1479.         {
  1480.             MethodSymbol *constructor = GeneratedConstructor(i);
  1481.             VariableSymbol *symbol = constructor -> block_symbol -> FindVariableSymbol(local -> Identity());
  1482.             if (! symbol)
  1483.             {
  1484.                 symbol = constructor -> block_symbol -> InsertVariableSymbol(local -> Identity());
  1485.                 symbol -> MarkSynthetic();
  1486.                 symbol -> SetType(variable -> Type());
  1487.                 symbol -> SetOwner(constructor);
  1488.                 symbol -> SetExternalIdentity(external_name_symbol);
  1489.                 symbol -> SetLocalVariableIndex(constructor -> block_symbol -> max_variable_index++);
  1490.                 if (symbol -> Type() == control.long_type || symbol -> Type() == control.double_type)
  1491.                     constructor -> block_symbol -> max_variable_index++;
  1492.                 constructor -> AddFormalParameter(symbol);
  1493.             }
  1494.         }
  1495.     }
  1496.  
  1497.     return variable;
  1498. }
  1499.  
  1500.  
  1501. MethodSymbol *TypeSymbol::GetReadAccessMethod(MethodSymbol *member)
  1502. {
  1503.     if (! member -> read_method)
  1504.     {
  1505.         TypeSymbol *type = member -> containing_type;
  1506.         Semantic *sem = type -> semantic_environment -> sem;
  1507.         Control &control = sem -> control;
  1508.         StoragePool *ast_pool = sem -> compilation_unit -> ast_pool;
  1509.  
  1510.         wchar_t info[12],
  1511.                 *str = &info[11];
  1512.         int n = (member -> Identity() == control.init_name_symbol ? type -> NumPrivateAccessConstructors()
  1513.                                                                   : type -> NumPrivateAccessMethods());
  1514.         *str = U_NULL;
  1515.         do
  1516.         {
  1517.             *--str = (U_0 + n % 10);
  1518.             n /= 10;
  1519.         } while (n != 0);
  1520.  
  1521.         int length = 7 + (&info[11] - str); // +7 for access$
  1522.         wchar_t *name = new wchar_t[length + 1]; // +1 for '\0';
  1523.         wcscpy(name, StringConstant::US__access_DOLLAR);
  1524.         wcscat(name, str);
  1525.  
  1526.         BlockSymbol *block_symbol = new BlockSymbol(member -> NumFormalParameters() + 3);
  1527.  
  1528.         MethodSymbol *method = type -> InsertMethodSymbol(control.FindOrInsertName(name, length));
  1529.         method -> MarkSynthetic();
  1530.         method -> SetType(member -> Type());
  1531.         if (member -> ACC_STATIC())
  1532.         {
  1533.             method -> SetACC_STATIC();
  1534.             block_symbol -> max_variable_index = 0;
  1535.         }
  1536.         else block_symbol -> max_variable_index = 1;
  1537.         method -> SetContainingType(type);
  1538.         method -> SetBlockSymbol(block_symbol);
  1539.  
  1540.         for (int i = 0; i < member -> NumThrows(); i++)
  1541.             method -> AddThrows(member -> Throws(i));
  1542.  
  1543.         //
  1544.         //
  1545.         //
  1546.         if (member -> Identity() != control.init_name_symbol) // not a constructor
  1547.         {
  1548.             for (int i = 0; i < member -> NumFormalParameters(); i++)
  1549.             {
  1550.                 VariableSymbol *parm = method -> block_symbol -> InsertVariableSymbol(member -> FormalParameter(i) -> Identity());
  1551.                 parm -> MarkSynthetic();
  1552.                 parm -> SetType(member -> FormalParameter(i) -> Type());
  1553.                 parm -> SetOwner(method);
  1554.                 parm -> SetLocalVariableIndex(block_symbol -> max_variable_index++);
  1555.                 if (parm -> Type() == control.long_type || parm -> Type() == control.double_type)
  1556.                     block_symbol -> max_variable_index++;
  1557.                 method -> AddFormalParameter(parm);
  1558.             }
  1559.             method -> SetSignature(control);
  1560.             // A read access method has no throws clause !
  1561.  
  1562.             type -> AddPrivateAccessMethod(method);
  1563.         }
  1564.         else
  1565.         {
  1566.             method -> SetExternalIdentity(member -> Identity());
  1567.  
  1568.             Ast *declaration = member -> method_or_constructor_declaration;
  1569.             AstMethodDeclaration *method_declaration = declaration -> MethodDeclarationCast();
  1570.             AstMethodDeclarator *declarator = (method_declaration
  1571.                                                      ? method_declaration -> method_declarator
  1572.                                                      : ((AstConstructorDeclaration *) declaration) -> constructor_declarator);
  1573.             LexStream::TokenIndex loc = declarator -> identifier_token;
  1574.  
  1575.             AstMethodDeclarator *method_declarator      = ast_pool -> GenMethodDeclarator();
  1576.             method_declarator -> identifier_token        = loc;
  1577.             method_declarator -> left_parenthesis_token  = declarator -> LeftToken();
  1578.             method_declarator -> right_parenthesis_token = declarator -> RightToken();
  1579.  
  1580.             AstThisCall *this_call = ast_pool -> GenThisCall();
  1581.             this_call -> base_opt                = NULL;
  1582.             this_call -> this_token              = loc;
  1583.             this_call -> left_parenthesis_token  = loc;
  1584.             this_call -> right_parenthesis_token = loc;
  1585.             this_call -> semicolon_token         = loc;
  1586.             this_call -> symbol = member;
  1587.  
  1588.             VariableSymbol *this0_variable = NULL;
  1589.             if (type -> IsInner())
  1590.             {
  1591.                 this0_variable = block_symbol -> InsertVariableSymbol(control.this0_name_symbol);
  1592.                 this0_variable -> MarkSynthetic();
  1593.                 this0_variable -> SetType(type -> ContainingType());
  1594.                 this0_variable -> SetOwner(method);
  1595.                 this0_variable -> SetLocalVariableIndex(block_symbol -> max_variable_index++);
  1596.             }
  1597.             for (int i = 0; i < member -> NumFormalParameters(); i++)
  1598.             {
  1599.                 VariableSymbol *parm = method -> block_symbol -> InsertVariableSymbol(member -> FormalParameter(i) -> Identity());
  1600.                 parm -> MarkSynthetic();
  1601.                 parm -> SetType(member -> FormalParameter(i) -> Type());
  1602.                 parm -> SetOwner(method);
  1603.                 parm -> SetLocalVariableIndex(block_symbol -> max_variable_index++);
  1604.                 if (parm -> Type() == control.long_type || parm -> Type() == control.double_type)
  1605.                     block_symbol -> max_variable_index++;
  1606.                 method -> AddFormalParameter(parm);
  1607.  
  1608.                 //
  1609.                 // Since private_access_constructors will compiled (see body.cpp), we must create
  1610.                 // valid ast_simple_names for its parameters.
  1611.                 //
  1612.                 AstVariableDeclaratorId *variable_declarator_name = declarator -> FormalParameter(i) -> variable_declarator_name;
  1613.                 AstSimpleName *simple_name = ast_pool -> GenSimpleName(variable_declarator_name -> identifier_token);
  1614.                 simple_name -> symbol = parm;
  1615.                 this_call -> AddArgument(simple_name);
  1616.             }
  1617.             method -> SetSignature(control, this0_variable);
  1618.             // A read access method has no throws clause !
  1619.  
  1620.             AstReturnStatement *return_statement = ast_pool -> GenReturnStatement();
  1621.             return_statement -> return_token = loc;
  1622.             return_statement -> expression_opt = NULL;
  1623.             return_statement -> semicolon_token = loc;
  1624.             return_statement -> is_reachable = true;
  1625.  
  1626.             AstBlock *block = ast_pool -> GenBlock();
  1627.             block -> AllocateBlockStatements(1); // this block contains one statement
  1628.             block -> left_brace_token  = loc;
  1629.             block -> right_brace_token = loc;
  1630.  
  1631.             block -> is_reachable = true;
  1632.             block -> can_complete_normally = false;
  1633.             block -> AddStatement(return_statement);
  1634.  
  1635.             AstConstructorBlock *constructor_block                   = ast_pool -> GenConstructorBlock();
  1636.             constructor_block -> left_brace_token                    = loc;
  1637.             constructor_block -> explicit_constructor_invocation_opt = this_call;
  1638.             constructor_block -> block                               = block;
  1639.             constructor_block -> right_brace_token                   = loc;
  1640.  
  1641.             AstConstructorDeclaration *constructor_declaration  = ast_pool -> GenConstructorDeclaration();
  1642.             constructor_declaration -> constructor_declarator   = method_declarator;
  1643.             constructor_declaration -> constructor_body         = constructor_block;
  1644.  
  1645.             constructor_declaration -> constructor_symbol = method;
  1646.             method -> method_or_constructor_declaration = constructor_declaration;
  1647.  
  1648.             if (type -> IsLocal())
  1649.                 sem -> GenerateLocalConstructor(method);
  1650.  
  1651.             type -> AddPrivateAccessConstructor(method);
  1652.         }
  1653.  
  1654.         method -> accessed_member = member;
  1655.         member -> read_method = method;
  1656.  
  1657.         delete [] name;
  1658.     }
  1659.  
  1660.     return member -> read_method;
  1661. }
  1662.  
  1663.  
  1664. MethodSymbol *TypeSymbol::GetReadAccessMethod(VariableSymbol *member)
  1665. {
  1666.     if (! member -> read_method)
  1667.     {
  1668.         TypeSymbol *type = member -> owner -> TypeCast();
  1669.         Semantic *sem = type -> semantic_environment -> sem;
  1670.         Control &control = sem -> control;
  1671.  
  1672.         wchar_t info[12],
  1673.                 *str = &info[11];
  1674.         int n = type -> NumPrivateAccessMethods();
  1675.         *str = U_NULL;
  1676.         do
  1677.         {
  1678.             *--str = (U_0 + n % 10);
  1679.             n /= 10;
  1680.         } while (n != 0);
  1681.  
  1682.         int length = 7 + (&info[11] - str); // +7 for access$
  1683.         wchar_t *name = new wchar_t[length + 1]; // +1 for '\0';
  1684.         wcscpy(name, StringConstant::US__access_DOLLAR);
  1685.         wcscat(name, str);
  1686.  
  1687.         MethodSymbol *method = type -> InsertMethodSymbol(control.FindOrInsertName(name, length));
  1688.         method -> MarkSynthetic();
  1689.         method -> SetType(member -> Type());
  1690.         if (member -> ACC_STATIC())
  1691.             method -> SetACC_STATIC();
  1692.         method -> SetContainingType(type);
  1693.         // No block_symbol is associated with an access method !
  1694.         // A read access method for a field has no formal parameters !
  1695.         method -> SetSignature(control);
  1696.         // A read access method has no throws clause !
  1697.  
  1698.         method -> accessed_member = member;
  1699.         member -> read_method = method;
  1700.         type -> AddPrivateAccessMethod(method);
  1701.  
  1702.         delete [] name;
  1703.     }
  1704.  
  1705.     return member -> read_method;
  1706. }
  1707.  
  1708.  
  1709. MethodSymbol *TypeSymbol::GetWriteAccessMethod(VariableSymbol *member)
  1710. {
  1711.     if (! member -> write_method)
  1712.     {
  1713.         TypeSymbol *type = member -> owner -> TypeCast();
  1714.         Semantic *sem = type -> semantic_environment -> sem;
  1715.         Control &control = sem -> control;
  1716.  
  1717.         wchar_t info[12],
  1718.                 *str = &info[11];
  1719.         int n = type -> NumPrivateAccessMethods();
  1720.         *str = U_NULL;
  1721.         do
  1722.         {
  1723.             *--str = (U_0 + n % 10);
  1724.             n /= 10;
  1725.         } while (n != 0);
  1726.  
  1727.         int length = 7 + (&info[11] - str); // +7 for access$
  1728.         wchar_t *name = new wchar_t[length + 1]; // +1 for '\0';
  1729.         wcscpy(name, StringConstant::US__access_DOLLAR);
  1730.         wcscat(name, str);
  1731.  
  1732.         MethodSymbol *method = type -> InsertMethodSymbol(control.FindOrInsertName(name, length));
  1733.         method -> MarkSynthetic();
  1734.         method -> SetType(sem -> control.void_type);
  1735.         if (member -> ACC_STATIC())
  1736.             method -> SetACC_STATIC();
  1737.         method -> SetContainingType(type);
  1738.         method -> SetBlockSymbol(new BlockSymbol(3)); // the associated symbol table will contain 1 element
  1739.         //
  1740.         // A write access method takes exactly one argument of the same type
  1741.         // as the variable. For a member named "m", its body will consist of
  1742.         // the single statement:
  1743.         //
  1744.         //    this.m = m;
  1745.         //
  1746.         VariableSymbol *symbol = method -> block_symbol -> InsertVariableSymbol(member -> Identity());
  1747.         symbol -> MarkSynthetic();
  1748.         symbol -> SetType(member -> Type());
  1749.         method -> AddFormalParameter(symbol);
  1750.  
  1751.         method -> SetSignature(control);
  1752.         // A write access method has no throws clause !
  1753.  
  1754.         method -> accessed_member = member;
  1755.         member -> write_method = method;
  1756.         type -> AddPrivateAccessMethod(method);
  1757.  
  1758.         delete [] name;
  1759.     }
  1760.  
  1761.     return member -> write_method;
  1762. }
  1763.